const express = require('express');
const { exec } = require('child_process');
const fs = require('fs');
const path = require('path');
const app = express();
const port = 3000;

// 中间件
app.use(express.json());
app.use(express.static('public'));

// 执行Git命令的工具函数
const executeGitCommand = (command, cwd) => {
  return new Promise((resolve, reject) => {
    exec(command, { cwd }, (error, stdout, stderr) => {
      if (error) {
        reject({ error, stderr });
        return;
      }
      resolve(stdout);
    });
  });
};

// API: 初始化仓库
app.post('/api/init', async (req, res) => {
  const { repoPath } = req.body;
  try {
    await executeGitCommand('git init', repoPath);
    res.json({ success: true, message: '仓库初始化成功' });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 获取仓库状态
app.post('/api/status', async (req, res) => {
  const { repoPath } = req.body;
  try {
    const status = await executeGitCommand('git status --porcelain', repoPath);
    res.json({ success: true, status });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 添加文件
app.post('/api/add', async (req, res) => {
  const { repoPath, files } = req.body;
  try {
    await executeGitCommand(`git add ${files.join(' ')}`, repoPath);
    res.json({ success: true, message: '文件添加成功' });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 提交更改
app.post('/api/commit', async (req, res) => {
  const { repoPath, message } = req.body;
  try {
    await executeGitCommand(`git commit -m "${message}"`, repoPath);
    res.json({ success: true, message: '提交成功' });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 获取提交历史
app.post('/api/log', async (req, res) => {
  const { repoPath } = req.body;
  try {
    const log = await executeGitCommand('git log --oneline', repoPath);
    res.json({ success: true, log });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 查询分支
app.post('/api/branches', async (req, res) => {
  const { repoPath } = req.body;
  try {
    const branches = await executeGitCommand('git branch -a', repoPath);
    const currentBranch = await executeGitCommand('git branch --show-current', repoPath);
    const branchList = branches.split('\n').map(branch => {
      const branchName = branch.trim().replace(/^\*\s*/, '');
      return {
        name: branchName,
        current: branchName === currentBranch.trim(),
        remote: branch.includes('remotes/')
      };
    }).filter(branch => branch.name);
    res.json({ success: true, branches: branchList, current: currentBranch.trim() });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 切换分支
app.post('/api/checkout', async (req, res) => {
  const { repoPath, branch } = req.body;
  try {
    await executeGitCommand(`git checkout ${branch}`, repoPath);
    res.json({ success: true, message: `已切换到分支: ${branch}` });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 创建新分支
app.post('/api/create-branch', async (req, res) => {
  const { repoPath, branchName } = req.body;
  try {
    await executeGitCommand(`git checkout -b ${branchName}`, repoPath);
    res.json({ success: true, message: `已创建新分支: ${branchName}` });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 取消暂存
app.post('/api/reset', async (req, res) => {
  const { repoPath, files } = req.body;
  try {
    if (files && files.length > 0) {
      await executeGitCommand(`git reset HEAD ${files.join(' ')}`, repoPath);
      res.json({ success: true, message: '已取消暂存指定文件' });
    } else {
      await executeGitCommand('git reset HEAD', repoPath);
      res.json({ success: true, message: '已取消暂存所有文件' });
    }
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 删除分支
app.post('/api/delete-branch', async (req, res) => {
  const { repoPath, branchName, force = false } = req.body;
  try {
    const forceFlag = force ? '-D' : '-d';
    await executeGitCommand(`git branch ${forceFlag} ${branchName}`, repoPath);
    res.json({ success: true, message: `已删除分支: ${branchName}` });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 推送到远程仓库
app.post('/api/push', async (req, res) => {
  const { repoPath, remote = 'origin', branch } = req.body;
  try {
    // 如果没有指定分支，获取当前分支
    let targetBranch = branch;
    if (!targetBranch) {
      targetBranch = await executeGitCommand('git branch --show-current', repoPath);
      targetBranch = targetBranch.trim();
    }
    
    await executeGitCommand(`git push ${remote} ${targetBranch}`, repoPath);
    res.json({ success: true, message: `已推送到远程仓库 ${remote}/${targetBranch}` });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 添加远程仓库
app.post('/api/add-remote', async (req, res) => {
  const { repoPath, name, url } = req.body;
  try {
    await executeGitCommand(`git remote add ${name} ${url}`, repoPath);
    res.json({ success: true, message: `已添加远程仓库: ${name}` });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// API: 获取远程仓库列表
app.post('/api/remotes', async (req, res) => {
  const { repoPath } = req.body;
  try {
    const remotes = await executeGitCommand('git remote -v', repoPath);
    const remoteList = remotes.split('\n').filter(line => line.trim()).map(line => {
      const parts = line.trim().split(/\s+/);
      return {
        name: parts[0],
        url: parts[1],
        type: parts[2] ? parts[2].replace(/[()]/g, '') : ''
      };
    }).filter((remote, index, self) => 
      index === self.findIndex(r => r.name === remote.name)
    );
    res.json({ success: true, remotes: remoteList });
  } catch (err) {
    res.status(500).json({ success: false, error: err.stderr });
  }
});

// 启动服务器
app.listen(port, () => {
  console.log(`Git可视化工具运行在 http://localhost:${port}`);
});
    